﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers;
using Rhino.Mocks;
using SimpleServiceBus.Bus.MessageManagement;
using SimpleServiceBus.Bus.MessageManagement.Serialization;
using SimpleServiceBus.Endpoint;

namespace SimpleServiceBus.Tests.Bus.MessageManagement.Serialization
{
    [TestFixture]
    public class SerializationTestFixture
    {
        private EndpointServiceManager _services;
        private IMessagingEndpoint _ep;
        private IMessageTypeManagementService _typeManager;


        [TestFixtureSetUp]
        public void SetUp()
        {
            _ep = MockRepository.GenerateStub<IMessagingEndpoint>();
            _services = new EndpointServiceManager(_ep);

            _typeManager = MockRepository.GenerateStub<IMessageTypeManagementService>();
            _services.RegisterService<IMessageTypeManagementService>(_typeManager);

            _services.Start();
        }

        [Test]
        public void XmlMessageSerializer_Serialize_Then_Deserialize_Test()
        {
            _typeManager.Stub(action => action.GetRegisteredMessageTypes()).Return(new[] { typeof(XmlSerializableMessage) });
            _ep.Stub(action => action.LocalServices).Return(_services);

            XmlMessageSerializer serializer = new XmlMessageSerializer();
            
            serializer.Endpoint = _ep;
            serializer.Start();

            _typeManager.AssertWasCalled(x => x.GetRegisteredMessageTypes());
            
            MemoryStream stream = new MemoryStream();
            serializer.Serialize(new XmlSerializableMessage {Hello = "Hello There"}, stream);

            Assert.That(stream.Length, Is.GreaterThan(0L));
            
            stream.Position = 0;
            var msg = serializer.Deserialize(stream) as XmlSerializableMessage;
            Assert.IsNotNull(msg);
            Assert.That(msg.Hello, Is.EqualTo("Hello There"));
        }

        [Test]
        public void DataContractSerializer_Serialize_Then_Deserialize_Test()
        {
            _typeManager.Stub(action => action.GetRegisteredMessageTypes()).Return(new[]
                                                                                       {typeof (XmlSerializableMessage)});
            _ep.Stub(action => action.LocalServices).Return(_services);

            DataContractMessageSerializer serializer = new DataContractMessageSerializer();

            serializer.Endpoint = _ep;
            serializer.Start();

            _typeManager.AssertWasCalled(x => x.GetRegisteredMessageTypes());

            MemoryStream stream = new MemoryStream();
            serializer.Serialize(new XmlSerializableMessage {Hello = "Hello There"}, stream);

            Assert.That(stream.Length, Is.GreaterThan(0L));

            stream.Position = 0;
            var msg = serializer.Deserialize(stream) as XmlSerializableMessage;
            Assert.IsNotNull(msg);
            Assert.That(msg.Hello, Is.EqualTo("Hello There"));
        }

        [Test]
        public void BinarySerialize_Serialize_Then_Deserialize_Test()
        {
            BinaryMessageSerializer serializer = new BinaryMessageSerializer();

            MemoryStream stream = new MemoryStream();
            serializer.Serialize(new XmlSerializableMessage {Hello = "Hello There"}, stream);

            Assert.That(stream.Length, Is.GreaterThan(0L));

            stream.Position = 0;
            var msg = serializer.Deserialize(stream) as XmlSerializableMessage;
            Assert.IsNotNull(msg);
            Assert.That(msg.Hello, Is.EqualTo("Hello There"));

        }
    }

    [Serializable][DataContract]
    public class XmlSerializableMessage
    {
        [DataMember]
        public string Hello { get; set; }
    }
}
